﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SimplexEngine
{
    public abstract class Light : StaticMeshEntity
    {
        public Light(String scene_object_name, String mesh_name) : base(scene_object_name, mesh_name)
        {
        }

        public virtual Boolean CanCastShadow { get { return false; } }
        public virtual Boolean CastShadow 
        {
            get { return cast_shadow; }
            set { cast_shadow = CanCastShadow && value; }
        }
        protected Boolean cast_shadow = false;
        
        public override int ObjectFilter { get { return (int)SceneObjectFilter.LIGHT; } }
    }

    public class DirectionalLight : Light
    {
        public DirectionalLight(String scene_object_name) : base(scene_object_name, "Plane.Shape")
        {
            material = new MRTDirectionLightMaterial();
            static_mesh_instance.SetMaterialToAllPart(material, false, false);
        }

        public Vector3 Direction { get { return material.Direction; } set { material.Direction = value; } }
        public Color Diffuse { get { return material.Diffuse; } set { material.Diffuse = value; } }

        protected MRTDirectionLightMaterial material = null;
        public override int ObjectFilter { get { return base.ObjectFilter | (int)SceneObjectFilter.HUGE; } }
    }

    public class PointLight : Light
    {
        public PointLight(String scene_object_name) : base(scene_object_name, "Sphere.Shape")
        {
            material = new MRTPointLightMaterial();
            static_mesh_instance.SetMaterialToAllPart(material, false, false);
            CalculateBoundingBox();
        }
        
        protected virtual void CalculateBoundingBox()
        {
            aabb = new BoundingBox(new Vector3(-Range), new Vector3(Range));
        }

        public Color Diffuse { get { return material.Diffuse; } set { material.Diffuse = value; } }
        public float Range { get { return material.Range; } set { material.Range = value; CalculateBoundingBox(); } }

        protected MRTPointLightMaterial material = null;
    }

    public class LightFactory : SceneObjectFactory
    {
        public override string Type
        {
            get { return "LIGHT"; }
        }

        public override SceneObject CreateSceneObject(String name, Dictionary<String, String> parameters)
        {
            switch (parameters["Type"])
            { 
                case "Direction":
                    return new DirectionalLight(name);
                case "Point":
                    return new PointLight(name);
            }

            return null;
        }
    }
}
